class MYPromise {
    // 构造方法
    constructor(executor) {
        // 添加属性
        this.PromiseState = 'pending'  // 状态值
        this.PromiseResult = null // 结果值
        // 因为实参函数内this指向的是wendow 所以需要保存this的指向值
        const self = this
        // 声明属性 接受then方法的回调函数
        this.callback = []
        //定义resolve实参函数 
        function resolve(data) {
            // 判断状态 因为Promise的状态值只能更改一次 如果已经修改了状态值 直接return
            if (self.PromiseState !== 'pending') return
            // 修改成功的状态值 
            self.PromiseState = 'fulfilled' // resolved
            // 修改成功的结果值 
            self.PromiseResult = data
            // 调用成功的回调函数 遍历回调数组
            // then方法是异步的 添加一个定时器 模拟异步
            setTimeout(() => {
                self.callback.forEach(i => {
                    i.onResolved(data)
                })
            })

        }
        // 定义reject实参函数
        function reject(data) {
            // 判断状态 因为Promise的状态值只能更改一次 如果已经修改了状态值 直接return
            if (self.PromiseState !== 'pending') return
            // 修改失败的状态值 
            self.PromiseState = 'rejectd' // rejectd
            // 修改成功的结果值 
            self.PromiseResult = data
            // 调用失败的回调函数 遍历回调数组
            // then方法是异步的 添加一个定时器 模拟异步
            setTimeout(() => {
                self.callback.forEach(i => {
                    i.onRejectd(data)
                })
            })

        }

        // throw 抛出异常改变状态
        try {
            // 同步调用 【执行器函数】 接收传过来的参数
            executor(resolve, reject)
        } catch (err) {
            reject(err)
        }
    }

    // 封装then方法
    then(onResolved, onRejectd) {
        // 改变this指向
        const self = this
        // 因为catch可以异常穿透  判断回调函数不为 undefined 而是一个funtion
        // 设置一个默认值
        if (typeof onRejectd !== 'function') {
            onRejectd = reason => {
                throw reason
            }
        }
        if (typeof onResolved !== 'function') {
            onResolved = value => value
        }
        return new MYPromise((resolve, reject) => {
            // 因为处理代码都写的一样 除了回调函数不一样 封装一个函数 
            function callback(onType) {
                // 用 try 捕获抛出异常
                try {
                    // 实参是Promise实例返回的结果值
                    const Result = onType(self.PromiseResult)
                    // 判断then返回的是不是一个Promise类型对象 
                    if (Result instanceof MYPromise) {
                        Result.then(res => {
                            resolve(res)
                        }, rej => {
                            reject(rej)
                        })
                    } else {
                        // 如果不是Promise类型的对象 直接调成功的Promise
                        resolve(Result)
                    }
                } catch (err) {
                    reject(err)
                }
            }
            // 判断状态是否为成功
            if (this.PromiseState === 'fulfilled') {
                // then方法是异步的 添加一个定时器 模拟异步
                setTimeout(() => {
                    callback(onResolved)
                })
            }
            // 判断状态是否为失败
            if (this.PromiseState === 'rejectd') {
                // then方法是异步的 添加一个定时器 模拟异步
                setTimeout(() => {
                    callback(onRejectd)
                })
            }
            // 判断状态是否为进行中 处理异步任务 保存回调函数
            if (this.PromiseState === 'pending') {
                // 考虑到会执行多个回调函数 所以用push
                this.callback.push({
                    onResolved: () => {
                        callback(onResolved)
                    }
                    ,
                    onRejectd: () => {
                        callback(onRejectd)
                    }
                })
            }
        })
    }

    // 封装catch方法
    catch(onRejectd) {
        // 返回一个Promise 因为then方法功能都实现了 
        return this.then(undefined, onRejectd)
    }

    // static 关键词 声明是一个静态成员 不是实例对象的方法
    static resolve(value) {
        // 返回一个Promise
        return new MYPromise((resolve, reject) => {
            // 判断是否为一个Promise
            if (value instanceof MYPromise) {
                value.then(res => { resolve(res) }, rej => { reject(rej) })
            } else {
                resolve(value)
            }
        })
    }

    // static 关键词 声明是一个静态成员 不是实例对象的方法
    static reject(reason) {
        // 返回一个失败的Promise
        return new MYPromise((resolve, reject) => {
            reject(reason)
        })
    }

    // static 关键词 声明是一个静态成员 不是实例对象的方法
    static all(Result) {
        // 返回一个Promise 结果值是n个Promise结果值的数组
        return new MYPromise((resolve, reject) => {
            // 声明一个数组 接收n个Promise的结果值
            var arr = []
            // 声明一个变量 接收执行次数
            var count = 0
            // 循环遍历Resut
            for (let i = 0; i < Result.length; i++) {
                Result[i].then(res => {
                    // 得知状态是成功 每一个Promise都成功 自增
                    count++
                    // 将当前成功的Promise存入到arr数组
                    arr[i] = res
                    if (count === Result.length) {
                        //修改状态
                        resolve(arr)
                    }
                }, rej => {
                    reject(rej)
                })
            }
        })
    }

    // static 关键词 声明是一个静态成员 不是实例对象的方法
    static race(Result) {
        return new MYPromise((resolve, reject) => {
            for (let i = 0; i < Result.length; i++) {
                Result[i].then(res => {
                    // 将状态修改为【成功】
                    resolve(res)
                }, rej => {
                    // 将状态修改为【失败】
                    reject(rej)
                })
            }
        })
    }

}




